package com.company.bookstore.controller.user_admin_module;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.company.bookstore.aspect.CIAM;
import com.company.bookstore.common.constant.RequestConstant;
import com.company.bookstore.common.redis.RedisUtil;
import com.company.bookstore.common.result.MvcResult;
import com.company.bookstore.entities.order_module.Order;
import com.company.bookstore.entities.user_admin_module.Address;
import com.company.bookstore.entities.user_admin_module.User;
import com.company.bookstore.exception.user_admin_module.CustomException;
import com.company.bookstore.qo.user_admin_module.AddressQo;
import com.company.bookstore.qo.user_admin_module.UserQo;
import com.company.bookstore.service.user_admin_module.AddressService;
import com.company.bookstore.service.user_admin_module.UserService;
import com.company.bookstore.test.CustomProducer;
import com.company.bookstore.validator.user_admin_module.*;
import com.company.bookstore.vo.UserVo;
import com.mchange.v1.util.ListUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author 吴经纶
 * @blame Android Team
 * @since 2020-08-27
 */
@CrossOrigin(origins = "*",maxAge = 3600)
@Api(tags = "用户相关接口", description = "提供用户相关的 Rest API")
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Resource
    UserService userService;
    @Resource
    AddressService addressService;
    @Resource
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Resource
    RedisUtil redisUtil;
    @Resource
    CustomProducer customProducer;

    public static Integer result;
    @CIAM(methodName = "buySecondKillBook")
    @PostMapping("/secondKill")
    public MvcResult<Object> buySecondKillBook(@RequestBody Order order) throws CustomException {
        if (order.getOrderAdd() == null){
            return MvcResult.builder().code(400).message("请填写地址信息").object(0).build();
        }
        if (!redisUtil.isSecondKillBookStarted(order.getFkBookId())){
            return MvcResult.builder().code(400).message("秒杀还未开始").object(0).build();
        }
        if (redisUtil.isSecondKillBook(order.getFkBookId(),order.getFkUserId())){
            return MvcResult.builder().code(400).message("您已经成功购买过该商品，请不要重复购买").object(0).build();
        }
        if (result!=null&&result<=0){
            return MvcResult.builder().code(400).message("该商品已经卖完").object(0).build();
        }
        result = redisUtil.buySecondKill(order.getFkBookId());
        if (result<=0){
            return MvcResult.builder().code(400).message("该商品已经卖完").object(0).build();
        }
        ArrayList<Order> orders = new ArrayList<>();
        orders.add(order);
        if (customProducer.syncSend(orders)){
            redisUtil.secondKillBook(order.getFkBookId(),order.getFkUserId());
            return MvcResult.builder().code(200).message("成功购买商品").object(result-1).build();
        }
        return MvcResult.builder().code(500).message("没有成功购买商品").build();
    }

    @ApiOperation(value = "删除地址接口")
    @DeleteMapping("/address")
    public MvcResult<Object> delAddress(@RequestParam Integer id)  {
        try {
            if (id == null){
                return MvcResult.builder().code(400).message("请指定参数").build();
            }
            if (addressService.removeById(id)){
                return MvcResult.builder().code(200).message("删除成功").build();
            }else {
                return MvcResult.builder().code(500).message("删除失败").build();
            }
        }catch (Exception e){
            e.printStackTrace();
            return MvcResult.builder().code(500).message("数据发送错误").build();
        }
    }

    @ApiOperation(value = "获取地址接口")
    @GetMapping("/address")
    public MvcResult<Object> getAddress(@RequestParam Integer userId) throws NoSuchMethodException, CustomException {
//        ValidatorFactory.Invoke(AddressRegisterValidator.class.getName(),addressQo);
        log.info("Method getAddress accept  params : {}",userId);
        try {
            QueryWrapper<Address> queryWrapper = new QueryWrapper<Address>();
            queryWrapper.eq("fk_user_id",userId);
            List<Address> addressList = addressService.list(queryWrapper);
            User u = userService.getById(userId);
            addressList.forEach(v->{
                if (u.getFkAddressId().equals(v.getId())){
                    v.setIsDefault(true);
                }
            });

            return MvcResult.builder().code(200).message("成功获取用户地址").object(addressList).build();
        }catch (Exception e){
            e.printStackTrace();
            return MvcResult.builder().code(500).message(e.getMessage()).build();
        }
    }
    @ApiOperation(value = "修改地址接口")
    @PutMapping("/address")
    public MvcResult<Object> modifyAddress(@RequestBody AddressQo addressQo) throws NoSuchMethodException, CustomException {
            ValidatorFactory.Invoke(AddressQoUpdateValidator.class.getName(),addressQo);
            try {
                Address address = Address.builder().build();
                BeanUtils.copyProperties(addressQo,address);
                if (addressService.updateById(address)){
                    return MvcResult.builder().code(200).message("成功修改用户地址").build();
                }else {
                    return MvcResult.builder().code(500).message("修改用户地址失败").build();
                }
            }catch (Exception e){
                e.printStackTrace();
                return MvcResult.builder().code(500).message(e.getMessage()).build();
            }
    }
    @ApiOperation(value = "添加地址接口")
    @PostMapping("/address")
    public MvcResult<Object> addAddress(@RequestBody AddressQo addressQo) throws NoSuchMethodException, CustomException {
        ValidatorFactory.Invoke(AddressRegisterValidator.class.getName(),addressQo);
        try {
            Address address = Address.builder().build();
            BeanUtils.copyProperties(addressQo,address);
            if (addressService.save(address)) {
                if (addressQo.getIsDefault()){
                    if (userService.updateUserQo(UserQo.builder().id(addressQo.getFkUserId()).fkAddressId(address.getId()).build())) {
                        return MvcResult.builder().code(200).message("成功添加用户地址").build();
                    }
                }else {
                    return MvcResult.builder().code(200).message("成功添加用户地址").build();
                }
            }
            return MvcResult.builder().code(500).message("添加用户地址失败").build();

        }catch (Exception e){
            e.printStackTrace();
            return MvcResult.builder().code(500).message(e.getMessage()).build();
        }
    }




    @ApiIgnore
    @ApiOperation("测试用户token")
    @GetMapping("/test")
    public MvcResult<Object> test(HttpServletRequest request){
        try {
            log.info(request.getHeader(RequestConstant.HTTP_LOGIN_JWT_HEADER));
            return MvcResult.LOGING_SUCCESS;
        }catch (Exception e){
            e.printStackTrace();
            return MvcResult.LOGING_ERROR;
        }
    }



    @ApiOperation("用户信息接口")
    @GetMapping("/getInfo")
    public MvcResult<Object> getInfo()  {
//        HttpServletRequest request =((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
//        String token = request.getHeader(RequestConstant.HTTP_LOGIN_JWT_HEADER);
        try {
            String username =  SecurityContextHolder.getContext().getAuthentication().getName();
            User user = (User) userService.loadUserByUsername(username);
            UserVo userVo = UserVo.builder().build();
            BeanUtils.copyProperties(user,userVo);
            userVo.setAddress(addressService.getById(user.getFkAddressId()));
            return MvcResult.builder().object(user).code(200).message("获取信息成功").object(userVo).build();
        }catch (Exception e){
            return MvcResult.builder().message(e.getMessage()).code(500).build();
        }
    }


    @ApiOperation("用户注册接口")
    @PostMapping("/register")
    public MvcResult<Object> register(@RequestBody UserQo userQo) throws NoSuchMethodException, CustomException {
            ValidatorFactory.Invoke(UserQoRegisterValidator.class.getName(),userQo);
            if (!userService.save(userQo.getUsername(),bCryptPasswordEncoder.encode(userQo.getPassword()))){
                return MvcResult.REGISTER_FAIL;
            }
            return MvcResult.REGISTER_SUCCESS;
    }

    @ApiOperation("用户资料修改接口")
    @PutMapping("")
    public MvcResult<Object> update(@RequestBody UserQo userQo) throws NoSuchMethodException, CustomException {
        if (userService.updateUserQo(userQo)){
            return MvcResult.FIX_USER_SUCCESS;
        }else {
            return MvcResult.FIX_USER_FAIL;
        }
    }


}

